home *** CD-ROM | disk | FTP | other *** search
/ Java Certification Exam Guide / McGrawwHill-JavaCertificationExamGuide.iso / pc / Web Links and Code / code / chap27 / answer / Server.java < prev    next >
Encoding:
Java Source  |  1997-04-20  |  7.9 KB  |  305 lines

  1. package server;
  2.  
  3. import java.io.*;
  4. import java.net.*;
  5.  
  6. /**
  7.  * The DataServer processes requests from clients to access the 
  8.  * database.
  9.  * The DataServer runs until you hit control-c. It is a multithreaded
  10.  *   server and spins off threads to process each connection from 
  11.  *   a client.
  12.  * @see server.DB
  13.  * @version 1.0
  14.  * @author Barry Boone
  15.  */
  16. public class Server {
  17.  
  18.    /** opcode for making a reservation. */
  19.    public static final int OP_MAKE_RESERVATION = 1;
  20.  
  21.    /** opcode for deleting a reservation. */
  22.    public static final int OP_DELETE = 2;
  23.  
  24.    /** opcode for getting a passenger's seat. */
  25.    public static final int OP_GET_SEAT = 3;
  26.  
  27.    /** opcode for getting all open seats. */
  28.    public static final int OP_GET_OPEN_SEATS = 4;
  29.  
  30.    /** opcode for getting all passengers. */
  31.    public static final int OP_GET_PASSENGER_LIST = 5;
  32.  
  33.    private int port = 5001;
  34.    private boolean listening = true;
  35.    private DB db;
  36.    private ServerSocket serverSock;
  37.  
  38.    /** Start the database server spinning. */
  39.    public static void main(String args[]) {
  40.       int portnum = 5001;
  41.  
  42.       System.out.println("The Server runs until you hit control-c");
  43.  
  44.       try {
  45.          Server server = new Server();
  46.          server.start();
  47.       } catch (IOException x) {
  48.          System.out.println("Could not create server socket: " +
  49.             x.getMessage());
  50.          System.exit(1);
  51.       }
  52.    }
  53.  
  54.    /**
  55.     * Put the Server object into action.
  56.     * @exception IOException thrown if we cannot create a ServerSocket
  57.     *     bound to the specified port
  58.     */
  59.    public void start() throws IOException {
  60.  
  61.       serverSock = null;
  62.       Socket sock; 
  63.  
  64.       db = new DB();
  65.  
  66.       try {         
  67.          serverSock = new ServerSocket(port, 50);
  68.  
  69.          while (listening) {
  70.      
  71.              // Wait for a client to connect with the server socket.
  72.              // Then spin off a thread to handle the connection 
  73.              // with the client, repeat.
  74.              try {
  75.                 // Wait here until contacted by a client.
  76.                 sock = serverSock.accept();
  77.  
  78.                 new ClientServerThread(sock, db).start();
  79.              } catch (IOException e) {
  80.                 System.out.println("Connection dropped?: " +
  81.                    e.getMessage());
  82.              }
  83.           }
  84.  
  85.        } finally {
  86.           serverSock.close();
  87.           serverSock = null;
  88.        }
  89.    }
  90.  
  91.    protected void finalize() throws Throwable {
  92.       super.finalize();
  93.       if (serverSock != null) {
  94.          serverSock.close();
  95.          serverSock = null;
  96.       }
  97.    }
  98. }
  99.  
  100. // Handles one transaction with a client.
  101. class ClientServerThread extends Thread {
  102.   
  103.    private static final int SUCCESS = 0;
  104.    private static final int FAILURE = 1;
  105.  
  106.    private static final int PAUSE_FOR = 50;
  107.  
  108.    private DB db;
  109.    private Socket sock;
  110.    private DataInputStream remoteIn;
  111.    private DataOutputStream remoteOut;
  112.  
  113.    ClientServerThread(Socket sock, DB db) {
  114.       this.sock = sock;
  115.       this.db = db;
  116.    }
  117.  
  118.    // Ths run() method processes just one request from a client and 
  119.    // then ends.
  120.    public void run() {      
  121.       try {
  122.          remoteIn = new DataInputStream(sock.getInputStream());
  123.          remoteOut = new DataOutputStream(sock.getOutputStream());
  124.  
  125.          // Get the opcode so we know how to handle this transaction.
  126.          int opcode = remoteIn.readInt();
  127.  
  128.          switch (opcode) {         
  129.             case (Server.OP_MAKE_RESERVATION):
  130.                 makeReservation();
  131.                 break;
  132.             case (Server.OP_DELETE):
  133.                 delete();
  134.                 break;
  135.             case (Server.OP_GET_SEAT):
  136.                 getSeat();
  137.                 break;
  138.             case (Server.OP_GET_OPEN_SEATS):
  139.                 getOpenSeats();
  140.                 break;
  141.             case (Server.OP_GET_PASSENGER_LIST):
  142.                 getPassengerList();
  143.                 break;
  144.             default:
  145.                 done();
  146.                 return;
  147.          }
  148.  
  149.       } catch (IOException e) {
  150.           error(e);
  151.       }
  152.    }
  153.  
  154.     // Make a reservation.
  155.     // in:  <opcode> <passenger name> <seat number>
  156.     // out: <0 OR 1 (success or failure)>
  157.     private void makeReservation() {
  158.        try {
  159.           String name = remoteIn.readUTF();
  160.           int seat = remoteIn.readInt();
  161.           db.reservePassenger(name, seat);
  162.           sendToClient(SUCCESS);
  163.        } catch (SeatTakenException x) {
  164.           sendToClient(FAILURE);
  165.        } catch (IOException x) {
  166.           System.out.println(x.getMessage());
  167.           sendToClient(FAILURE);
  168.        } finally {
  169.           done();
  170.        }
  171.     }
  172.  
  173.     // Delete a reservation.
  174.     // in:  <opcode> <passenger name>
  175.     // out: <0 OR 1 (success or failure)>
  176.     private void delete() {
  177.        try {
  178.           String name = remoteIn.readUTF();
  179.           db.deletePassenger(name);
  180.           sendToClient(SUCCESS);
  181.        } catch (IOException e) {
  182.           error(e);
  183.           sendToClient(FAILURE);
  184.        } finally {
  185.           done();
  186.        }
  187.     }
  188.  
  189.     // Get a seat given a passenger.
  190.     // in:  <opcode> <passenger name>
  191.     // out: <seat number> (-1 if no seat found)
  192.     private void getSeat()
  193.     {
  194.        try {
  195.           String name = remoteIn.readUTF();
  196.           int seat = db.getSeat(name);
  197.           sendToClient(seat);
  198.        } catch (Exception x) {
  199.           sendToClient(FAILURE); 
  200.        } finally {
  201.           done();
  202.        }
  203.     }
  204.  
  205.     // Get all open seats.
  206.     // in:  <opcode> 
  207.     // out: <number of open seats> { <seat number> }
  208.     private void getOpenSeats()
  209.     {
  210.        try {
  211.           int[] seats = db.getOpenSeats();
  212.           sendToClient(seats.length);
  213.           for (int i = 0; i < seats.length; i++)
  214.              sendToClient(seats[i]);
  215.        } catch (Exception x) {
  216.        } finally {
  217.           done();
  218.        }
  219.     }
  220.  
  221.     // Get passenger list.
  222.     // in:  <opcode> 
  223.     // out: <number of passengers> { <passenger name> }
  224.     private void getPassengerList()
  225.     {
  226.        try {
  227.           String[] passengers = db.getPassengerList();
  228.           sendToClient(passengers.length);
  229.           for (int i = 0; i < passengers.length; i++)
  230.              sendToClient(passengers[i]);
  231.        } catch (Exception x) {
  232.        } finally {
  233.           done();
  234.        }
  235.     }
  236.  
  237.     // Close the connection with the client.
  238.     private void done() {
  239.        try {
  240.           if (remoteOut != null) {
  241.              remoteOut.close();
  242.              remoteOut = null;
  243.           }
  244.  
  245.           if (remoteIn != null) {             
  246.              remoteIn.close();
  247.              remoteIn = null;
  248.           }
  249.        } catch (IOException x) {
  250.           error(x);
  251.        } finally {
  252.           try {
  253.              if (sock != null) {
  254.                 sock.close();
  255.                 sock = null;
  256.              }
  257.           } catch (IOException x) {
  258.              error(x);
  259.           }
  260.        }
  261.     }
  262.  
  263.     private void sendToClient(int i) {
  264.        try {
  265.           remoteOut.writeInt(i);
  266.        } catch (IOException x) {
  267.           error(x);
  268.        }
  269.  
  270.        pause();
  271.     }
  272.  
  273.     private void sendToClient(String s) {
  274.        try {
  275.           remoteOut.writeUTF(s);
  276.        } catch (IOException x) {
  277.           error(x);
  278.        }
  279.  
  280.        pause();
  281.     }
  282.  
  283.     // On Windows95, at least, when the client and server are running on
  284.     // the same machine, we have to pause for the client to read 
  285.     // the data when the server writes it to the socket. 
  286.     // Otherwise, the client hangs.
  287.     private void pause() {
  288.        try {
  289.           sleep(PAUSE_FOR);
  290.        } catch (InterruptedException x) {
  291.           error(x);
  292.        }
  293.     }
  294.  
  295.     private void error(Exception x) {
  296.        System.out.println("Connection dropped?: " + x.getMessage());
  297.     }
  298.  
  299.     protected void finalize() throws Throwable {
  300.        super.finalize();
  301.        done();
  302.     }
  303.  
  304. }
  305.